<?php
/**
 * @package Application_Acl
 * @author Cezar Zaleski e Reginaldo Júnior
 * @version 1.0.0
 */

/**
 * @namespace
 */
namespace Application\Acl;
/**
 * @uses Doctrine\ORM\EntityManager
 * @uses Zend\Permissions\Acl\Acl
 * @uses Zend\Permissions\Acl\Role\GenericRole
 * @uses Zend\Permissions\Acl\Resource\GenericResource
 * @uses Application\Auth\UsuarioAuth
 */
use Doctrine\ORM\EntityManager;
use Zend\Permissions\Acl\Acl;
use Zend\Permissions\Acl\Role\GenericRole as Role;
use Zend\Permissions\Acl\Resource\GenericResource as Resource;
use Application\Auth\UsuarioAuth;
/**
 * Classe para definição dos papéis, recursos e privilégios dos usuários na aplicação 
 */
class Autorizacao extends Acl{
	/**
	 * @var EntityManager
	 */
	protected $em;
	/**
	 * Repository autilizado
	 * @var Doctrine\ORM\EntityRepository
	 */
	protected $repository;
	/**
	 * Instancia de Zend\Permissions\Alc\Acl
	 * @var Zend\Permissions\Alc\Acl
	 */
	protected $_acl;
	/**
	 * Papéis utilizados na aplicação
	 * @var Zend\Permissions\Acl\Role\GenericRole
	 */
	protected $_roles;
	/**
	 * Recursos utilizados na aplicação
	 * @var Zend\Permissions\Acl\Resource\GenericResource
	 */
	protected $_resources;
	/**
	 * Perfil do usuário autencicado
	 * @var integer
	 */
	protected $_idPerfil;
	/**
	 * Construtor
	 * @access public
	 * @param EntityManager $em
	 * @return void
	 */
	public function __construct(EntityManager $em) {
		$this->em = $em;
		$this->_acl = new Acl();
		$this->_initialize();
	}
	
    /**
     * Inicializa os métodos de criar os papéis e recursos da aplicação
     * @access protected
     * @return void
     */
    protected function _initialize() {
    	$this->_addRoles();
    	$this->_addResources();
    	$usuarioAuth = new UsuarioAuth();
    	if($usuarioAuth->getLoggedUser()){
    		$this->_setupPrivileges($usuarioAuth->getLoggedUser()->idPerfil);
    	}
    	
    }
	/**
	 * Define os papéis da aplicação
	 * @access protected
	 * @return void
	 */
    protected function _addRoles(){
    	$this->repository = $this->em->getRepository('Application\Entity\Perfil');
    	$this->_roles = $this->repository->findAll();
    	if(!empty($this->_roles)){
    		foreach ($this->_roles as $val){
    			$this->_acl->addRole(new Role($val->getNoPerfil()));
    		}
    	}
    	$this->getRoles();
    }
    /**
     * Define os recursos da aplicação
     * @access protected
     * @return void
     */
    protected function _addResources() {
    	$this->repository = $this->em->getRepository('Application\Entity\Submodulo');
    	$this->_resources = $this->repository->findAll();
    	$this->_acl->addResource(new Resource("loading-menu"));
    	if(!empty($this->_resources)){
    		foreach ($this->_resources as $val){
    			$resource = $val->getIdModulo()->getNoModulo().':'.$val->getNoSubmodulo();
    			$this->_acl->addResource(new Resource($resource));
    		}
    	}
    	
    }
    /**
     * Define os privilégios dos usuários
     * @access protected
     * @param $idPerfil
     * @return void
     */
    protected function _setupPrivileges($idPerfil) {
     	$this->repository = $this->em->getRepository('Application\Entity\Funcionalidade');
    	$funcionalidade = $this->repository->findAll();
    	if(!empty($funcionalidade)){
    		foreach ($funcionalidade as $val){
    			$resource = $val->getIdSubmodulo()->getIdModulo()->getNoModulo().':'.$val->getIdSubmodulo()->getNoSubmodulo();
    			foreach ($this->_roles as $value){
    				$this->_acl->deny($value->getNoPerfil(),$resource,$val->getIdTipoFuncionalidade()->getNoTipoFuncionalidade());
    			}
    		}
    		//buscar funcionalidades do perfil
    		$this->repository = $this->em->getRepository('Application\Entity\Funcionalidade');
    		$perfilFunc =$this->repository->findByFuncPerfil($idPerfil);
    		if(!empty($perfilFunc)){
    			$this->_acl->allow($value->getNoPerfil(),"loading-menu");
    			foreach ($perfilFunc as $val){
    				$resource = $val['noModulo'].':'.$val['noSubmodulo'];
    				foreach ($this->_roles as $value){
    					$this->_acl->allow($value->getNoPerfil(),$resource,$val['noTipoFuncionalidade']);
    				}
    			}
    		} 
    	}
    }
    
    public function verificaAutorizacao($controller, $action,$perfil)
    {
    	$return = true;
    	if(!$this->_acl->hasResource($controller)){
    		$return = false;
    	}else if(!$this->_acl->isAllowed($perfil,$controller,$action)){
    		$return = false; 
    	}
    	return $return;
    }
    
    public function getResources()
    {
    	return $this->_acl->getResources();
    }
    
}
